package com.cyanite.playlv2.preferences;

import com.cyanite.playlv2api.PlayLv2Api;
import com.cyanite.playlv2api.error.PlayLv2ApiCredentialsException;
import com.cyanite.playlv2api.error.PlayLv2ApiException;
import com.cyanite.playlv2api.types.City;
import com.cyanite.playlv2api.types.User;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.preference.PreferenceManager;

import java.io.IOException;
import java.util.UUID;

public class Preferences {

    // Visible Preferences (sync with preferences.xml)
    public static final String PREFERENCE_SHARE_CHECKIN = "share_checkin";
    public static final String PREFERENCE_IMMEDIATE_CHECKIN = "immediate_checkin";
    public static final String PREFERENCE_STARTUP_TAB = "startup_tab";

    // Hacks for preference activity extra UI elements.
    public static final String PREFERENCE_FRIEND_REQUESTS = "friend_requests";
    public static final String PREFERENCE_FRIEND_ADD = "friend_add";
    public static final String PREFERENCE_CITY_NAME = "city_name";
    public static final String PREFERENCE_LOGOUT = "logout";
    public static final String PREFERENCE_HELP = "help";
    public static final String PREFERENCE_PINGS = "pings_on";
    public static final String PREFERENCE_PINGS_INTERVAL = "pings_refresh_interval_in_minutes";
    public static final String PREFERENCE_PINGS_VIBRATE = "pings_vibrate";
    public static final String PREFERENCE_TOS_PRIVACY = "tos_privacy";
    public static final String PREFERENCE_PROFILE_SETTINGS = "profile_settings";
    public static final String PREFERENCE_PROFILE_SYNC = "sync";

    // Credentials related preferences
    public static final String PREFERENCE_LOGIN = "phone";
    public static final String PREFERENCE_PASSWORD = "password";
    //
    public static final String PREFERENCE_BLOG_SINA = "sina";
    public static final String PREFERENCE_BLOG_KAIXIN001 = "kaixin001";
    public static final String PREFERENCE_BLOG_RENREN = "renren";
    public static final String PREFERENCE_BLOG_MSN = "msn";
    public static final String PREFERENCE_BLOG_GTALK = "gtalk";


    // TODO 4
    public final static String DOUBAN_REQUEST_TOKEN = "douban_request_token";
    public final static String DOUBAN_REQUEST_TOKEN_SECRET = "douban_request_token_secret";
    public final static String DOUBAN_ACCESS_TOKEN = "douban_access_token";
    public final static String DOUBAN_ACCESS_TOKEN_SECRET = "douban_access_token_secret";


    // Extra info for getUserCity
    private static final String PREFERENCE_CITY_ID = "city_id";
    private static final String PREFERENCE_CITY_GEOLAT = "city_geolat";
    private static final String PREFERENCE_CITY_GEOLONG = "city_geolong";
    private static final String PREFERENCE_CITY_SHORTNAME = "city_shortname";

    // Extra info for getUserId
    private static final String PREFERENCE_ID = "id";

    // Extra for storing user's supplied email address.
    private static final String PREFERENCE_USER_EMAIL = "user_email";

    // Extra for storing user's supplied first and last name.
    private static final String PREFERENCE_USER_NAME = "user_name";

    // Extra info about the user, their gender, to control icon used for 'me' in the UI.
    private static final String PREFERENCE_GENDER = "gender";

    // Extra info, can the user have followers or not.
    public static final String PREFERENCE_CAN_HAVE_FOLLOWERS = "can_have_followers";

    // Not-in-XML preferences for dumpcatcher
    public static final String PREFERENCE_DUMPCATCHER_CLIENT = "dumpcatcher_client";

    // Keeps track of the last changelog version shown to the user at startup.
    private static final String PREFERENCE_LAST_SEEN_CHANGELOG_VERSION
        = "last_seen_changelog_version";

    // User can choose to clear geolocation on each search.
    public static final String PREFERENCE_CACHE_GEOLOCATION_FOR_SEARCHES
        = "cache_geolocation_for_searches";

    // If we're compiled to show the prelaunch activity, flag stating whether to skip
    // showing it on startup.
    public static final String PREFERENCE_SHOW_PRELAUNCH_ACTIVITY = "show_prelaunch_activity";

    // Last time pings service ran.
    public static final String PREFERENCE_PINGS_SERVICE_LAST_RUN_TIME = "pings_service_last_run_time";

    // Broadcast an intent to show single full-screen images, or use our own poor image viewer.
    public static final String PREFERENCE_NATIVE_IMAGE_VIEWER
        = "native_full_size_image_viewer";


    /**
     * Gives us a chance to set some default preferences if this is the first install
     * of the application.
     */
    public static void setupDefaults(SharedPreferences preferences, Resources resources) {
        Editor editor = preferences.edit();

        if (!preferences.contains(PREFERENCE_CACHE_GEOLOCATION_FOR_SEARCHES)) {
            editor.putBoolean(PREFERENCE_CACHE_GEOLOCATION_FOR_SEARCHES, false);
        }
        if (!preferences.contains(PREFERENCE_SHOW_PRELAUNCH_ACTIVITY)) {
            editor.putBoolean(PREFERENCE_SHOW_PRELAUNCH_ACTIVITY, true);
        }
        if (!preferences.contains(PREFERENCE_PINGS_INTERVAL)) {
            editor.putString(PREFERENCE_PINGS_INTERVAL, "30");
        }
        if (!preferences.contains(PREFERENCE_NATIVE_IMAGE_VIEWER)) {
            editor.putBoolean(PREFERENCE_NATIVE_IMAGE_VIEWER, false);
        }
        editor.commit();
    }

    public static String createUniqueId(SharedPreferences preferences) {
        String uniqueId = preferences.getString(PREFERENCE_DUMPCATCHER_CLIENT, null);
        if (uniqueId == null) {
            uniqueId = UUID.randomUUID().toString();
            Editor editor = preferences.edit();
            editor.putString(PREFERENCE_DUMPCATCHER_CLIENT, uniqueId);
            editor.commit();
        }
        return uniqueId;
    }

    public static boolean loginUser(PlayLv2Api playlv2api, String login, String password,
            PlayLv2Api.Location location, Editor editor) throws PlayLv2ApiCredentialsException,
            PlayLv2ApiException, IOException {

        playlv2api.setCredentials(login, password);
        storeLoginAndPassword(editor, login, password);
        if (!editor.commit()) {
            return false;
        }

        User user = playlv2api.user(null, false, false, location);
        storeUser(editor, user);
        if (!editor.commit()) {
            return false;
        }

        return true;
    }

    public static boolean loginUser(PlayLv2Api playlv2api, String account, String password, Editor editor)
                throws PlayLv2ApiCredentialsException, PlayLv2ApiException, IOException {

        playlv2api.setCredentials(account, password);
        storeLoginAndPassword(editor, account, password);
        if (!editor.commit()) {
            return false;
        }
        User user = playlv2api.login(account, password);
        storeUser(editor, user);
        if (!editor.commit()) {
            return false;
        }
        return true;
    }

    public static boolean signupUser(PlayLv2Api playlv2api, String account, String password, String phone,
            String email, String gender, String country, String province, String city, String street, Editor editor) throws PlayLv2ApiCredentialsException,
            PlayLv2ApiException, IOException {

        playlv2api.setCredentials(account, password);
        User user = playlv2api.signup(account, password, phone, email, gender, country, province, city, street);
        storeLoginAndPassword(editor, account, password);
        if (!editor.commit()) {
            return false;
        }
        storeUser(editor, user);
        if (!editor.commit()) {
            return false;
        }
        return true;
    }

    public static boolean logoutUser(PlayLv2Api playlv2api, Editor editor) {
        playlv2api.setCredentials(null, null);
        return editor.clear().commit();
    }

    public static City getUserCity(SharedPreferences prefs) {
        City city = new City();
        city.setId(prefs.getString(Preferences.PREFERENCE_CITY_ID, null));
        city.setName(prefs.getString(Preferences.PREFERENCE_CITY_NAME, null));
        city.setShortname(prefs.getString(Preferences.PREFERENCE_CITY_SHORTNAME, null));
        city.setGeolat(prefs.getString(Preferences.PREFERENCE_CITY_GEOLAT, null));
        city.setGeolong(prefs.getString(Preferences.PREFERENCE_CITY_GEOLONG, null));
        return city;
    }

    public static String getUserId(SharedPreferences prefs) {
        return prefs.getString(PREFERENCE_ID, null);
    }

    public static String getUserName(SharedPreferences prefs) {
        return prefs.getString(PREFERENCE_USER_NAME, null);
    }

    public static String getUserEmail(SharedPreferences prefs) {
        return prefs.getString(PREFERENCE_USER_EMAIL, null);
    }

    public static String getUserGender(SharedPreferences prefs) {
        return prefs.getString(PREFERENCE_GENDER, null);
    }

    public static boolean getBindStatusByIndex(SharedPreferences prefs, int index)  {
        switch ( index ){
            case 0:
                return prefs.getBoolean(PREFERENCE_BLOG_SINA, false);
            case 1:
                return prefs.getBoolean(PREFERENCE_BLOG_RENREN, false);
            case 2:
                return prefs.getBoolean(PREFERENCE_BLOG_KAIXIN001, false);
            case 3:
                return prefs.getBoolean(PREFERENCE_BLOG_MSN, false);
            case 4:
                return prefs.getBoolean(PREFERENCE_BLOG_GTALK, false);
            default:
                break;
        }
        return false;
    }

    public static void setBindStatusByIndex(SharedPreferences prefs, int index, boolean bindStatus)  {
        Editor editor = prefs.edit();
        switch ( index ){
            case 0:
                editor.putBoolean(PREFERENCE_BLOG_SINA, bindStatus);
            case 1:
                editor.putBoolean(PREFERENCE_BLOG_RENREN, bindStatus);
            case 2:
                editor.putBoolean(PREFERENCE_BLOG_KAIXIN001, bindStatus);
            case 3:
                editor.putBoolean(PREFERENCE_BLOG_MSN, bindStatus);
            case 4:
                editor.putBoolean(PREFERENCE_BLOG_GTALK, bindStatus);
            default:
                break;
        }
        editor.commit();
    }



    public static void saveSinaTokenPair(Context cxt, String pair1, String pair2) {
        Editor editor = PreferenceManager.getDefaultSharedPreferences(cxt).edit();
        editor.putString("sina_blog_token", pair1);
        editor.putString("sina_blog_tokensecret", pair2);
        editor.commit();
    }

    public static String readSinaToken(Context cxt) {
        return PreferenceManager.getDefaultSharedPreferences(cxt).getString("sina_blog_token", "");
    }

    public static String readSinaTokenSecret(Context cxt) {
        return PreferenceManager.getDefaultSharedPreferences(cxt).getString("sina_blog_tokensecret", "");
    }



    public static void saveDoubanAccessTokenPair(Context cxt, String pair1, String pair2) {
        Editor editor = PreferenceManager.getDefaultSharedPreferences(cxt).edit();
        editor.putString(DOUBAN_ACCESS_TOKEN, pair1);
        editor.putString(DOUBAN_ACCESS_TOKEN_SECRET, pair2);
        editor.commit();
    }

    public static String readDoubanAccessToken(Context cxt) {
        return PreferenceManager.getDefaultSharedPreferences(cxt).getString(DOUBAN_ACCESS_TOKEN, "");
    }

    public static String readDoubanAccessTokenSecret(Context cxt) {
        return PreferenceManager.getDefaultSharedPreferences(cxt).getString(DOUBAN_ACCESS_TOKEN_SECRET, "");
    }


    public static void saveDoubanRequestTokenPair(Context cxt, String pair1, String pair2) {
        Editor editor = PreferenceManager.getDefaultSharedPreferences(cxt).edit();
        editor.putString(DOUBAN_REQUEST_TOKEN, pair1);
        editor.putString(DOUBAN_REQUEST_TOKEN_SECRET, pair2);
        editor.commit();
    }

    public static String readDoubanRequestToken(Context cxt) {
        return PreferenceManager.getDefaultSharedPreferences(cxt).getString(DOUBAN_REQUEST_TOKEN, "");
    }

    public static String readDoubanRequestTokenSecret(Context cxt) {
        return PreferenceManager.getDefaultSharedPreferences(cxt).getString(DOUBAN_REQUEST_TOKEN_SECRET, "");
    }


    public static boolean getSinaBindStatus(SharedPreferences prefs) {
        return prefs.getBoolean(PREFERENCE_BLOG_SINA, false);
    }

    public static boolean getRenRenBindStatus(SharedPreferences prefs) {
        return prefs.getBoolean(PREFERENCE_BLOG_RENREN, false);
    }

    public static boolean getKaixin001BindStatus(SharedPreferences prefs) {
        return prefs.getBoolean(PREFERENCE_BLOG_KAIXIN001, false);
    }

    public static boolean getMsnBindStatus(SharedPreferences prefs) {
        return prefs.getBoolean(PREFERENCE_BLOG_MSN, false);
    }

    public static boolean getGTalkBindStatus(SharedPreferences prefs) {
        return prefs.getBoolean(PREFERENCE_BLOG_GTALK, false);
    }

    public static String getLastSeenChangelogVersion(SharedPreferences prefs) {
        return prefs.getString(PREFERENCE_LAST_SEEN_CHANGELOG_VERSION, null);
    }

    public static void storeCity(final Editor editor, City city) {
        if (city != null) {
            editor.putString(PREFERENCE_CITY_ID, city.getId());
            editor.putString(PREFERENCE_CITY_GEOLAT, city.getGeolat());
            editor.putString(PREFERENCE_CITY_GEOLONG, city.getGeolong());
            editor.putString(PREFERENCE_CITY_NAME, city.getName());
            editor.putString(PREFERENCE_CITY_SHORTNAME, city.getShortname());
        }
    }

    public static void storeLoginAndPassword(final Editor editor, String login, String password) {
        editor.putString(PREFERENCE_LOGIN, login);
        editor.putString(PREFERENCE_PASSWORD, password);
    }

    public static void storeUser(final Editor editor, User user) {
        if (user != null && user.getId() != null) {
            editor.putString(PREFERENCE_ID, user.getId());
            editor.putString(PREFERENCE_USER_NAME, user.getUserName());
            editor.putString(PREFERENCE_USER_EMAIL, user.getEmail());
            editor.putString(PREFERENCE_GENDER, user.getGender());
        }
    }

    public static void storeLastSeenChangelogVersion(final Editor editor, String version) {
        editor.putString(PREFERENCE_LAST_SEEN_CHANGELOG_VERSION, version);
        if (!editor.commit()) {
        }
    }

    public static boolean getUseNativeImageViewerForFullScreenImages(SharedPreferences prefs) {
        return prefs.getBoolean(PREFERENCE_NATIVE_IMAGE_VIEWER, true);
    }
}
